// Copyright (C) 1953-2021 NUDT
// Verilog module name - descriptor_select 
// Version: V3.2.0.20210727
// Created:
//         by - fenglin 
////////////////////////////////////////////////////////////////////////////
// Description:
//         control bufid and tsntag  to input queue
//              
//             
///////////////////////////////////////////////////////////////////////////

`timescale 1ns/1ps

module descriptor_select
(
       i_clk              ,
       i_rst_n            ,
                          
       iv_desp_1          ,
       i_desp_wr_1        ,
       o_desp_ack_1       ,
                          
       iv_desp_2          ,
       i_desp_wr_2        ,
       o_desp_ack_2       ,
                          
       iv_desp_3          ,
       i_desp_wr_3        ,
       o_desp_ack_3       ,
       
       ov_bufid           ,
       ov_ipv             ,
       o_bufid_wr       
);
// I/O
// clk & rst
input                  i_clk  ;
input                  i_rst_n;  
//tsntag & bufid input from host_port
(*MARK_DEBUG="true"*) input          [11:0]  iv_desp_1         ;
(*MARK_DEBUG="true"*) input                  i_desp_wr_1       ;
(*MARK_DEBUG="true"*) output reg             o_desp_ack_1      ;
(*MARK_DEBUG="true"*) input          [11:0]  iv_desp_2         ;
(*MARK_DEBUG="true"*) input                  i_desp_wr_2       ;
(*MARK_DEBUG="true"*) output reg             o_desp_ack_2      ;
(*MARK_DEBUG="true"*) input          [11:0]  iv_desp_3         ;
(*MARK_DEBUG="true"*) input                  i_desp_wr_3       ;
(*MARK_DEBUG="true"*) output reg             o_desp_ack_3      ;
//tsntag & bufid output
(*MARK_DEBUG="true"*) output reg     [8:0]   ov_bufid          ;
(*MARK_DEBUG="true"*) output reg     [2:0]   ov_ipv            ;
(*MARK_DEBUG="true"*) output reg             o_bufid_wr        ;
//***************************************************
//          control bufid to input queue 
//***************************************************
(*MARK_DEBUG="true"*)reg            [3:0]   niq_state;
localparam  IDLE_S = 4'd0,
            HOST_ST_REQUEST_PAUSE_S = 4'd1,
            HOST_RCBE_REQUEST_PAUSE_S = 4'd2,
            HCP_REQUEST_PAUSE_S = 4'd3,
            NETWORK_REQUEST_PAUSE_S = 4'd4;
always @(posedge i_clk or negedge i_rst_n) begin
    if(!i_rst_n) begin
        o_desp_ack_1   <= 1'b0;
        o_desp_ack_2 <= 1'b0;
        o_desp_ack_3       <= 1'b0;        
        
        ov_bufid             <= 9'b0;
        ov_ipv               <= 3'b0;
        o_bufid_wr           <= 1'b0;
        niq_state            <= IDLE_S;
    end
    else begin
        case(niq_state)
            IDLE_S:begin
                if(i_desp_wr_1 == 1'b1)begin
                    o_desp_ack_1   <= 1'b1;
                    ov_bufid             <= iv_desp_1[8:0];
                    ov_ipv               <= iv_desp_1[11:9];
                    o_bufid_wr           <= 1'b1;
                    
                    o_desp_ack_2 <= 1'b0;
                    o_desp_ack_3       <= 1'b0;   
                    niq_state            <= HOST_ST_REQUEST_PAUSE_S;                    
                end
                else if(i_desp_wr_2 == 1'b1)begin
                    o_desp_ack_2 <= 1'b1; 
                    ov_bufid             <= iv_desp_2[8:0];
                    ov_ipv               <= iv_desp_2[11:9];
                    o_bufid_wr           <= 1'b1;
                    
                    o_desp_ack_1   <= 1'b0;
                    o_desp_ack_3       <= 1'b0;   
                    niq_state            <= HOST_RCBE_REQUEST_PAUSE_S;                      
                end
                else if(i_desp_wr_3 == 1'b1)begin
                    o_desp_ack_3       <= 1'b1; 
                    ov_bufid             <= iv_desp_3[8:0];
                    ov_ipv               <= iv_desp_3[11:9];
                    o_bufid_wr           <= 1'b1;
                    
                    o_desp_ack_1   <= 1'b0;
                    o_desp_ack_2 <= 1'b0;   
                    niq_state            <= HCP_REQUEST_PAUSE_S;                      
                end                
                else begin
                    o_desp_ack_1   <= 1'b0;
                    o_desp_ack_2 <= 1'b0;
                    o_desp_ack_3       <= 1'b0;        
                    
                    ov_bufid             <= 9'b0;
                    ov_ipv               <= 3'b0;
                    o_bufid_wr           <= 1'b0;
                    niq_state            <= IDLE_S;
                end
            end
            HOST_ST_REQUEST_PAUSE_S:begin
                o_desp_ack_1       <= 1'b0;
                o_desp_ack_2     <= 1'b0;
                o_desp_ack_3           <= 1'b0;
                
                ov_bufid                 <= 9'b0;
                ov_ipv                   <= 3'b0;
                o_bufid_wr               <= 1'b0;             
                if(i_desp_wr_1 == 1'b0)begin
                    niq_state <= IDLE_S;
                end
                else begin
                    niq_state <= HOST_ST_REQUEST_PAUSE_S;
                end
            end
            HOST_RCBE_REQUEST_PAUSE_S:begin
                o_desp_ack_1       <= 1'b0;
                o_desp_ack_2     <= 1'b0;
                o_desp_ack_3           <= 1'b0;
                
                ov_bufid                 <= 9'b0;
                ov_ipv                   <= 3'b0;
                o_bufid_wr               <= 1'b0;             
                if(i_desp_wr_2 == 1'b0)begin
                    niq_state <= IDLE_S;
                end
                else begin
                    niq_state <= HOST_RCBE_REQUEST_PAUSE_S;
                end
            end            
            HCP_REQUEST_PAUSE_S:begin
                o_desp_ack_1       <= 1'b0;
                o_desp_ack_2     <= 1'b0;
                o_desp_ack_3           <= 1'b0;
                
                ov_bufid                 <= 9'b0;
                ov_ipv                   <= 3'b0;
                o_bufid_wr               <= 1'b0;             
                if(i_desp_wr_3 == 1'b0)begin
                    niq_state <= IDLE_S;
                end
                else begin
                    niq_state <= HCP_REQUEST_PAUSE_S;
                end
            end  
            default:begin
                o_desp_ack_1       <= 1'b0;
                o_desp_ack_2     <= 1'b0;
                o_desp_ack_3           <= 1'b0;
                
                ov_bufid                 <= 9'b0;
                ov_ipv                   <= 3'b0;
                o_bufid_wr               <= 1'b0;  
                niq_state                <= IDLE_S;                
            end
        endcase            
    end
end 
endmodule